package com.zk.config.web.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.github.zkclient.ZkClient;
import com.zk.config.api.util.ZkCom;
import com.zk.config.api.util.ZkOperate;
import com.zk.config.web.model.ConfigResponse;
import com.zk.config.web.model.NoAuthPerms;
import com.zk.config.web.model.Param;
import com.zk.config.web.model.TreeZkData;
import com.zk.config.web.util.ComUtil;
import com.zk.config.web.util.ConfUtils;

@Controller
@RequestMapping("")
public class IndexController {
    private static final Logger log = LoggerFactory.getLogger(IndexController.class);
    private String rootPath = ConfUtils.getConxtions().getProperty("ROOT");
    private Properties contentType = ConfUtils.getConxtions("contentType.properties");
    private ZkClient client = new ZkClient(rootPath);
//	@Value("${user}")
//	private String user;
//	@Value("${userName}")
//	private String userName;
//	@Resource
//	private Properties configProperties;
//	@Resource
//	private ConfigClient configClient;
//	@Resource
//	private ConfigClient configClient2;
//	@Resource
//	private Test test;
   @RequestMapping(value = { "", "/", "/index" })
   public ModelAndView index() {
		// 这里是测试注入的代码
//		System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$user="+ user + ",userName=" + userName);
		// 这里是测试注入的动态变化的值的代码
//		System.out.println("#######configProperties######user="+configProperties.getProperty("user") + ",userName=" + configProperties.getProperty("userName"));
//		System.out.println("#######ConfigClient.zkCache######user="+ZkCache.getPropertiesValue("user") + ",userName=" + ZkCache.getPropertiesValue("userName"));
//		System.out.println("#######configClient configClient2######user="+configClient.getZkCache().getPropertiesValue("user") + ",userName=" + configClient2.getZkCache().getPropertiesValue("userName"));
//		test.init();
		
      ModelAndView mav = new ModelAndView("index");
      mav.addObject("addrs", ConfUtils.getConxtions());
      return mav;
   }

   @RequestMapping("/getConfigData")
   public void getConfigData(HttpServletRequest request, HttpServletResponse response) {
       long startTime = System.currentTimeMillis();
       ConfigResponse res = new ConfigResponse();
       Param params = new Param();
       params.setPath(ComUtil.toStr(request.getParameter("path")));
       params.setKey(ComUtil.toStr(request.getParameter("key")));
       String wtStr = request.getParameter("wt");
       if(wtStr != null && contentType.containsKey(wtStr)) {
           params.setWt(wtStr);
       }
       params.setUserName(ComUtil.toStr(request.getParameter("userName")));
       params.setPassword(ComUtil.toStr(request.getParameter("password")));
//       String useCacheStr = request.getParameter("useCache");
//       boolean useCache = ComUtil.parseBoolean(useCacheStr);
       res.setParams(params);
       if(rootPath == null) {
           res.setState(-1);
           res.setMsg("no zookeeper root config.");
           res.setTime(System.currentTimeMillis()-startTime);
           ComUtil.writeResponse(response, res);
           return;
       }
       boolean result = false;
       if(StringUtils.isNotEmpty(params.getUserName()) && StringUtils.isNotEmpty(params.getPassword())) {
           ZkClient client2 = new ZkClient(rootPath);
           client2.getZooKeeper().addAuthInfo("digest", (params.getUserName()+":"+params.getPassword()).getBytes());
           result = getData(request, response, client2, res);
       } else {
           result = getData(request, response, this.client, res);
       }
       if(result) {
           res.setTime(System.currentTimeMillis()-startTime);
           ComUtil.writeResponse(response, res);
       }
   }
   
   private boolean getData(HttpServletRequest request, HttpServletResponse response, ZkClient client, ConfigResponse res) {
       Param params = res.getParams();
       if(StringUtils.isEmpty(params.getPath())) {
           res.setState(-2);
           res.setMsg("no path parameter.");
           return true;
       }
       String path = ZkCom.getZkPath(params.getPath());
       
       if(client == null || client.getZooKeeper() == null) {
           res.setState(-3);
           res.setMsg("zookeeper init error.");
           return true;
       }
       if(!"json".equals(params.getWt()) && StringUtils.isEmpty(params.getKey())) {
           byte[] data = ZkOperate.getNodeByte(client.getZooKeeper(), path, false, null);
           if(data != null && data.length > 0) {
               if(contentType.containsKey(params.getWt())) {
                   response.setContentType(contentType.getProperty(params.getWt()));
               } else {
                   response.setContentType("text/html;charset=UTF-8");
               }
               try {
                   OutputStream toClient = response.getOutputStream();
                   toClient.write(data);
                   toClient.flush();
                   toClient.close();
               } catch (IOException e) {
                   e.printStackTrace();
                   log.error(e.getMessage());
               }
           }
           return false;
       }
       TreeZkData td = new TreeZkData();
       StringBuilder keyInPath = new StringBuilder();
       List<NoAuthPerms> noAuthPathList = new ArrayList<>();
       Properties p = ComUtil.getChildren(client.getZooKeeper(), path, td, params.getKey(), keyInPath, noAuthPathList);
       if(StringUtils.isEmpty(td.getName()) || StringUtils.isNotEmpty(params.getKey()) && p ==null) {
           res.setState(-4);
           res.setMsg("no data found.");
           return true;
       }
       if(noAuthPathList.size() > 0) {
           res.setState(1);
           res.setNoAuthPaths(noAuthPathList);
           res.setMsg("NoAuthException.");
       }
       if(p == null) {
           res.setFoundPath(path);
           res.setData(td);
       } else {
           String data = p.getProperty(params.getKey());
           if(!"json".equals(params.getWt())) {
               if(StringUtils.isNotEmpty(data)) {
                   if(contentType.containsKey(params.getWt())) {
                       response.setContentType(contentType.getProperty(params.getWt()));
                   } else {
                       response.setContentType("text/html;charset=UTF-8");
                   }
                   try {
                       response.getWriter().print(data);
                   } catch (IOException e) {
                       e.printStackTrace();
                       log.error(e.getMessage());
                   }
               }
               return false;
           }
           res.setFoundPath(keyInPath.toString());
           res.setData(data);
       }
       return true;
   }
}
